home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 04 - 1988 / 04.04 Apr 88 / TearOffPalette Source / TearOffPalette.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-29  |  17.1 KB  |  704 lines  |  [TEXT/KAHL]

  1. /*
  2. ----------------------------------------------------------------------------------------------------
  3. T E A R O F F   P A L E T T E
  4.  
  5.     version 1.0
  6.     by Don Melton and Mike Ritter
  7.     
  8.     Copyright (C)1987, 1988 by Impulse Technologies, Inc., all rights reserved. 
  9.     
  10.     Filename:            TearOffPalette.c
  11.     Font:                    Monaco, 9 point
  12.     Tab setting:    2
  13.     Compiler:            LightspeedC 2.15, Project type: APPL, Creator: TOPD
  14.     Segment:            Main
  15.  
  16. ----------------------------------------------------------------------------------------------------
  17. DESCRIPTION
  18.  
  19.     TearOffPalette is a demonstration of a very portable method of implementing tear-off menus and
  20.     floating palettes. This technique uses external MDEF and WDEF code resources. The MDEF
  21.     communicates with the application via a TearOffMenuGlobals structure in a TOMG resource.
  22.     
  23.     See TearOffMDEF.c for an explanation of the TearOffMenuGlobals structure and the routines an
  24.     application must contain to use TearOffMDEF.
  25.     
  26.     See PaletteWDEF.c for an explanation of the behavior and use of PaletteWDEF.
  27.     
  28.     TearOffPalette is designed to keep palettes floating above documents without directly writing to
  29.     low-memory Window Manager globals.
  30.     
  31.     A Color menu and palette will be displayed when Color QuickDraw is present and the depth of the
  32.     screen allows 256 colors.
  33.     
  34.     Under MultiFinder and at any Suspend or Resume event, TearOffPalette will hide or show all visible
  35.     palettes.
  36.     
  37.     IMPORTANT! TearOffPalette.project.rsrc must contain the TearOffMDEF and PaletteWDEF resources
  38.     created by compiling their respective source files. */
  39.  
  40.  
  41.  
  42. /*
  43. ----------------------------------------------------------------------------------------------------
  44. GLOBAL CONSTANT DEFINITIONS AND VARIABLE DECLARATIONS */
  45.  
  46. #define GLOBAL_VARIABLES
  47.  
  48. #include "Constants.h"
  49. #include "Variables.h"
  50.  
  51. /*
  52. ----------------------------------------------------------------------------------------------------
  53. EXTERNAL FUNCTION DECLARATIONS */
  54.  
  55. extern void Initialize();                                        /* Initialize.c */
  56. extern void DoAbout();                                            /* Dialog.c */
  57. extern void AdjustInterface();                            /* Interface.c */
  58. extern void LocateWindows();                                /* Palette.c */
  59. extern short ActiveWindow();                                /* Palette.c */
  60. extern void DoSelectWindow();                                /* Palette.c */
  61. extern void DoDragWindow();                                    /* Palette.c */
  62. extern void HiliteUserWindows();                        /* Palette.c */
  63. extern void ActivateDocument();                            /* Window.c */
  64. extern void UpdateDocument();                                /* Window.c */
  65. extern void SizeDocument();                                    /* Window.c */
  66. extern void UpdatePalette();                                /* Window.c */
  67. extern void NewDocument();                                    /* Window.c */
  68. extern void CloseDocument();                                /* Window.c */
  69. extern pascal short FindToolItem();                    /* Menu.c */
  70. extern pascal void HiliteToolItem();                /* Menu.c */
  71. extern pascal short FindPatternItem();            /* Menu.c */
  72. extern pascal void HilitePatternItem();            /* Menu.c */
  73. extern pascal short FindColorItem();                /* Menu.c */
  74. extern pascal void HiliteColorItem();                /* Menu.c */
  75. extern void MovePalette();                                    /* Menu.c */
  76.  
  77. /*
  78. ----------------------------------------------------------------------------------------------------
  79. FORWARD FUNCTION DECLARATIONS */
  80.  
  81. void DoEvent();
  82. void MouseDownEvent();
  83. void KeyEvent();
  84. void ActivateEvent();
  85. void UpdateEvent();
  86. void SuspendResumeEvent();
  87. void MenuEvent();
  88. void AppleMenu();
  89. void FileMenu();
  90. void EditMenu();
  91. void ToolMenu();
  92. void PatternMenu();
  93. void ColorMenu();
  94. void ContentEvent();
  95. void GrowEvent();
  96. void InvalGrow();
  97. void CloseEvent();
  98.  
  99.  
  100.  
  101. /*
  102. ----------------------------------------------------------------------------------------------------
  103. TEAROFF PALETTE */
  104.  
  105. main() {
  106.  
  107.     Initialize();
  108.     UnloadSeg(Initialize);
  109.     
  110.     DoAbout();
  111.     
  112.     while((!Finished) && (!OutOfMemory)) {
  113.         AdjustInterface();
  114.         DoEvent();
  115.     }
  116. }
  117.  
  118. /*
  119. ----------------------------------------------------------------------------------------------------
  120. DO EVENT */
  121.  
  122. void DoEvent() {
  123. Boolean result;
  124.  
  125.     if(WNEIsImplemented) {
  126.         result = WaitNextEvent(everyEvent, &Event, Sleep, nil);
  127.     }
  128.     else {
  129.         SystemTask();
  130.         result = GetNextEvent(everyEvent, &Event);
  131.     }
  132.     /* Find all application windows in the window list, and adjust their order if necessary.
  133.     IMPORTANT! Always call LocateWindows() after getting the event. */
  134.     LocateWindows();
  135.     
  136.     if(result) {
  137.     
  138.         switch(Event.what) {
  139.         
  140.             case mouseDown:
  141.             
  142.                 if(!(ClosingAll || Quitting)) {
  143.                     MouseDownEvent();
  144.                 }
  145.                 break;
  146.                 
  147.             case keyDown:
  148.             case autoKey:
  149.             
  150.                 if(!(ClosingAll || Quitting)) {
  151.                     KeyEvent();
  152.                 }
  153.                 break;
  154.                 
  155.             case updateEvt:
  156.                 UpdateEvent();
  157.                 break;
  158.                 
  159.             case activateEvt:
  160.                 ActivateEvent();
  161.                 break;
  162.                 
  163.             case app4Evt:
  164.                 SuspendResumeEvent();
  165.         }
  166.     }
  167.     else {
  168.     
  169.         if((ClosingAll || Quitting) && (Event.what == nullEvent)) {
  170.             /* If the application is quitting or the option key was held down when closing a window, the
  171.             top visible window is closed during each pass through the event loop until all windows are
  172.             closed. */
  173.         
  174.             if(TopWindow != nil) {
  175.                 CloseEvent(TopWindow);
  176.             }
  177.             else {
  178.                 ClosingAll = false;
  179.                 
  180.                 if(Quitting) {
  181.                     Finished = true;
  182.                 }
  183.             }
  184.         }
  185.     }
  186. }
  187.     
  188. /*
  189. ----------------------------------------------------------------------------------------------------
  190. MOUSEDOWN EVENT
  191.  
  192.     AcitiveWindow() replaces most traditional calls to FrontWindow(). All use of SelectWindow() and
  193.     DragWindow() is replaced by calls to DoSelectWindow() and DoDragWindow(). This ensures mouseDown
  194.     events in application windows handle floating palettes properly. */
  195.  
  196. void MouseDownEvent() {
  197.     WindowPtr whichWindow;
  198.     short whichPart;
  199.     
  200.     MouseInMenu = false;
  201.     
  202.     whichPart = FindWindow(Event.where, &whichWindow);
  203.     
  204.     switch(whichPart) {
  205.     
  206.         case inMenuBar:
  207.             MouseInMenu = true;
  208.             MenuEvent(MenuSelect(Event.where));
  209.             break;
  210.             
  211.         case inSysWindow:
  212.             SystemClick(&Event, whichWindow);
  213.             break;
  214.         
  215.         case inContent:  
  216.             if(!ActiveWindow(whichWindow)) {
  217.                 DoSelectWindow(whichWindow);
  218.             }
  219.             else {
  220.                 ContentEvent(whichWindow);
  221.             }
  222.             break;
  223.         
  224.         case inDrag: 
  225.             DoDragWindow(whichWindow);
  226.             break;
  227.             
  228.         case inGrow: 
  229.             if(!ActiveWindow(whichWindow)) {
  230.                 DoSelectWindow(whichWindow);
  231.             }
  232.             else {
  233.                 GrowEvent(whichWindow);
  234.             }
  235.             break;
  236.             
  237.         case inGoAway: 
  238.             if(!ActiveWindow(whichWindow)) {
  239.                 DoSelectWindow(whichWindow);
  240.             }
  241.             else {
  242.                 if(TrackGoAway(whichWindow, Event.where)) {
  243.                     CloseEvent(whichWindow);
  244.                 }
  245.             }
  246.             break;
  247.             
  248.         case inZoomIn:
  249.         case inZoomOut:
  250.             if(TrackBox(whichWindow, Event.where, whichPart)) {
  251.                 SetPort(whichWindow);
  252.                 EraseRect(&whichWindow->portRect);
  253.                 ZoomWindow(whichWindow, whichPart, false);
  254.                 SizeDocument(whichWindow);
  255.             }
  256.     }
  257. }
  258.  
  259. /*
  260. ----------------------------------------------------------------------------------------------------
  261. KEYDOWN AND AUTOKEY EVENT */
  262.  
  263. void KeyEvent() {
  264.     char whichChar;
  265.     
  266.     whichChar = Event.message & charCodeMask;
  267.  
  268.     if((Event.modifiers & cmdKey) != 0) {
  269.     
  270.         if(Event.what != autoKey) {
  271.             MenuEvent(MenuKey(whichChar));
  272.         }
  273.     }
  274. }
  275.  
  276. /*
  277. ----------------------------------------------------------------------------------------------------
  278. ACTIVATE EVENT */
  279.  
  280. void ActivateEvent() {
  281.     WindowPtr whichWindow;
  282.     
  283.     /* Ensure all application windows are hilited correctly. */
  284.     HiliteUserWindows();
  285.     whichWindow = (WindowPtr) Event.message;
  286.     
  287.     if(((WindowPeek) whichWindow)->refCon != DOCUMENT_WINDOW) {
  288.         /* Pass the activate event from a palette to the TopDocument. */
  289.         whichWindow = TopDocument;
  290.     }
  291.     if(whichWindow != nil) {
  292.         /* Ensure the document window's controls are properly visible and hilited. */
  293.         ActivateDocument(whichWindow, Event.modifiers & activeFlag);
  294.     }
  295. }
  296.  
  297. /*
  298. ----------------------------------------------------------------------------------------------------
  299. UPDATE EVENT */
  300.  
  301. void UpdateEvent() {
  302.     WindowPtr whichWindow;
  303.     
  304.     whichWindow = (WindowPtr) Event.message;
  305.     
  306.     SetPort(whichWindow);
  307.     
  308.     BeginUpdate(whichWindow);
  309.     
  310.     if(((WindowPeek) whichWindow)->refCon == DOCUMENT_WINDOW) {
  311.         UpdateDocument(whichWindow);
  312.     }
  313.     else {
  314.         UpdatePalette(whichWindow);
  315.     }
  316.     DrawControls(whichWindow);
  317.     DrawGrowIcon(whichWindow);
  318.     
  319.     EndUpdate(whichWindow);
  320. }
  321.  
  322. /*
  323. ----------------------------------------------------------------------------------------------------
  324. SUSPEND/RESUME EVENT 
  325.  
  326.     Hide all palettes when the application is not the active layer. This leaves the screen much less
  327.     cluttered. */
  328.  
  329. void SuspendResumeEvent() {
  330.     short index;
  331.     
  332.     for(index = 0; index < PALETTE_COUNT; index++) {
  333.     
  334.         if((Event.message & 1) == 0) {
  335.             PalettesVisible[index] = ((WindowPeek) Palettes[index])->visible;
  336.             ShowHide(Palettes[index], false);
  337.         }
  338.         else {
  339.             ShowHide(Palettes[index], PalettesVisible[index]);
  340.             PalettesVisible[index] = false;
  341.         }
  342.     }
  343.     LocateWindows();
  344.     HiliteUserWindows();
  345.     
  346.     if((((WindowPeek) TopWindow)->windowKind == userKind) && (TopDocument != nil)) {
  347.         /* Ensure the TopDocument's controls are properly visible and unhilited. */
  348.         ActivateDocument(TopDocument, (Boolean) Event.message & 1);
  349.     }
  350. }
  351.  
  352. /*
  353. ----------------------------------------------------------------------------------------------------
  354. MENU AND COMMAND KEY EVENT */
  355.  
  356. void MenuEvent(menuChoice)
  357. long menuChoice;
  358. {
  359.     short whichMenu;
  360.     short whichItem;
  361.     
  362.     whichMenu = menuChoice >> 16; /* HiWord(menuChoice). */
  363.     whichItem = menuChoice & 0xFFFF; /* LoWord(menuChoice). */
  364.     
  365.     switch(whichMenu) {
  366.     
  367.         case APPLE_MENU_ID:
  368.             AppleMenu(whichItem);
  369.             break;
  370.             
  371.         case FILE_MENU_ID:
  372.             FileMenu(whichItem);
  373.             break;
  374.             
  375.         case EDIT_MENU_ID:
  376.             EditMenu(whichItem);
  377.             break;
  378.             
  379.         case TOOL_MENU_ID:
  380.             ToolMenu(whichItem);
  381.             break;
  382.             
  383.         case PATTERN_MENU_ID:
  384.             PatternMenu(whichItem);
  385.             break;
  386.             
  387.         case COLOR_MENU_ID:
  388.             ColorMenu(whichItem);
  389.     }
  390.     HiliteMenu(0);
  391. }
  392.  
  393. /*
  394. ----------------------------------------------------------------------------------------------------
  395. SELECT APPLE MENU ITEM */
  396.  
  397. void AppleMenu(whichItem)
  398. short whichItem;
  399. {
  400.     Str255 daName;
  401.     
  402.     if(whichItem == ABOUT_ITEM) {
  403.         DoAbout();
  404.     }
  405.     else {
  406.         GetItem(Menus[APPLE_MENU_INDEX], whichItem, &daName);
  407.         /* Ignore the result returned by the ROM. */
  408.         (void) OpenDeskAcc(&daName);
  409.     }
  410. }
  411.  
  412. /*
  413. ----------------------------------------------------------------------------------------------------
  414. SELECT FILE MENU ITEM */
  415.  
  416. void FileMenu(whichItem)
  417. short whichItem;
  418. {
  419.     switch(whichItem) {
  420.     
  421.         case NEW_ITEM:
  422.             NewDocument();
  423.             break;
  424.             
  425.         case CLOSE_ITEM:
  426.             CloseEvent(TopDocument);
  427.             break;
  428.             
  429.         case QUIT_ITEM:
  430.             Quitting = true;
  431.             Sleep = 0;
  432.     }
  433. }
  434.  
  435. /*
  436. ----------------------------------------------------------------------------------------------------
  437. SELECT EDIT MENU ITEM */
  438.  
  439. void EditMenu(whichItem)
  440. short whichItem;
  441. {
  442.     (void) SystemEdit(whichItem - 1);
  443. }
  444.  
  445. /*
  446. ----------------------------------------------------------------------------------------------------
  447. SELECT TOOL MENU ITEM */
  448.  
  449. void ToolMenu(whichItem)
  450. short whichItem;
  451. {
  452.     WindowPtr paletteWindow;
  453.     
  454.     paletteWindow = Palettes[TOOL_PALETTE];
  455.     
  456.     if(whichItem == MOVE_PALETTE_ITEM) {
  457.         /* The menu has been torn off. */
  458.         MovePalette(paletteWindow, (*TearOffs[TOOL_PALETTE])->position);
  459.     }
  460.     else {
  461.     
  462.         if(whichItem != (*TearOffs[TOOL_PALETTE])->currentItem) {
  463.             SetPort(Palettes[TOOL_PALETTE]);
  464.             
  465.             /* Unhilte the old item. */
  466.             HiliteToolItem(&paletteWindow->portRect, (*TearOffs[TOOL_PALETTE])->currentItem, false);
  467.             /* Hilite the new item. */
  468.             HiliteToolItem(&paletteWindow->portRect, whichItem, true);
  469.             
  470.             /* Set the currentItem equal to the new item. */
  471.             (*TearOffs[TOOL_PALETTE])->currentItem = whichItem;
  472.         }
  473.     }
  474. }
  475.  
  476. /*
  477. ----------------------------------------------------------------------------------------------------
  478. SELECT PATTERN MENU ITEM */
  479.  
  480. void PatternMenu(whichItem)
  481. short whichItem;
  482. {
  483.     WindowPtr paletteWindow;
  484.     
  485.     paletteWindow = Palettes[PATTERN_PALETTE];
  486.     
  487.     if(whichItem == MOVE_PALETTE_ITEM) {
  488.         /* The menu has been torn off. */
  489.         MovePalette(paletteWindow, (*TearOffs[PATTERN_PALETTE])->position);
  490.     }
  491.     else {
  492.     
  493.         if(whichItem != (*TearOffs[PATTERN_PALETTE])->currentItem) {
  494.             SetPort(Palettes[PATTERN_PALETTE]);
  495.             
  496.             /* Unhilte the old item. */
  497.             HilitePatternItem(&paletteWindow->portRect, (*TearOffs[PATTERN_PALETTE])->currentItem, false);
  498.             /* Hilite the new item. */
  499.             HilitePatternItem(&paletteWindow->portRect, whichItem, true);
  500.             
  501.             /* Set the currentItem equal to the new item. */
  502.             (*TearOffs[PATTERN_PALETTE])->currentItem = whichItem;
  503.         }
  504.     }
  505. }
  506.  
  507. /*
  508. ----------------------------------------------------------------------------------------------------
  509. SELECT COLOR MENU ITEM */
  510.  
  511. void ColorMenu(whichItem)
  512. short whichItem;
  513. {
  514.     WindowPtr paletteWindow;
  515.     
  516.     paletteWindow = Palettes[COLOR_PALETTE];
  517.     
  518.     if(whichItem == MOVE_PALETTE_ITEM) {
  519.         /* The menu has been torn off. */
  520.         MovePalette(paletteWindow, (*TearOffs[COLOR_PALETTE])->position);
  521.     }
  522.     else {
  523.     
  524.         if(whichItem != (*TearOffs[COLOR_PALETTE])->currentItem) {
  525.             SetPort(Palettes[COLOR_PALETTE]);
  526.             
  527.             /* Unhilte the old item. */
  528.             HiliteColorItem(&paletteWindow->portRect, (*TearOffs[COLOR_PALETTE])->currentItem, false);
  529.             /* Hilite the new item. */
  530.             HiliteColorItem(&paletteWindow->portRect, whichItem, true);
  531.             
  532.             /* Set the currentItem equal to the new item. */
  533.             (*TearOffs[COLOR_PALETTE])->currentItem = whichItem;
  534.         }
  535.     }
  536. }
  537.  
  538. /*
  539. ----------------------------------------------------------------------------------------------------
  540. CONTENT EVENT */
  541.  
  542. void ContentEvent(whichWindow)
  543. WindowPtr whichWindow;
  544. {
  545.     Point mousePt;
  546.     short item;
  547.     
  548.     SetPort(whichWindow);
  549.     
  550.     mousePt = Event.where;
  551.     GlobalToLocal(&mousePt);
  552.     
  553.     /* Use the window's refCon to determine what type of application window received the event. */
  554.     switch(((WindowPeek) whichWindow)->refCon) {
  555.     
  556.         case TOOL_PALETTE:
  557.             item = FindToolItem(mousePt);
  558.             
  559.             if(item != (*TearOffs[TOOL_PALETTE])->currentItem) {
  560.                 /* Unhilte the old item. */
  561.                 HiliteToolItem(&whichWindow->portRect, (*TearOffs[TOOL_PALETTE])->currentItem, false);
  562.                 /* Hilite the new item. */
  563.                 HiliteToolItem(&whichWindow->portRect, item, true);
  564.                 
  565.                 /* Set the currentItem equal to the new item. */
  566.                 (*TearOffs[TOOL_PALETTE])->currentItem = item;
  567.             }
  568.             break;
  569.             
  570.         case PATTERN_PALETTE:
  571.             item = FindPatternItem(mousePt);
  572.             
  573.             if(item != (*TearOffs[PATTERN_PALETTE])->currentItem) {
  574.                 /* Unhilte the old item. */
  575.                 HilitePatternItem(&whichWindow->portRect, (*TearOffs[PATTERN_PALETTE])->currentItem, false);
  576.                 /* Hilite the new item. */
  577.                 HilitePatternItem(&whichWindow->portRect, item, true);
  578.                 
  579.                 /* Set the currentItem equal to the new item. */
  580.                 (*TearOffs[PATTERN_PALETTE])->currentItem = item;
  581.             }
  582.             break;
  583.             
  584.         case COLOR_PALETTE:
  585.             item = FindColorItem(mousePt);
  586.             
  587.             if(item != (*TearOffs[COLOR_PALETTE])->currentItem) {
  588.                 /* Unhilte the old item. */
  589.                 HiliteColorItem(&whichWindow->portRect, (*TearOffs[COLOR_PALETTE])->currentItem, false);
  590.                 /* Hilite the new item. */
  591.                 HiliteColorItem(&whichWindow->portRect, item, true);
  592.                 
  593.                 /* Set the currentItem equal to the new item. */
  594.                 (*TearOffs[COLOR_PALETTE])->currentItem = item;
  595.             }
  596.     }
  597. }
  598.  
  599. /*
  600. ----------------------------------------------------------------------------------------------------
  601. GROW EVENT */
  602.  
  603. void GrowEvent(whichWindow)
  604. WindowPtr whichWindow;
  605. {
  606.     Rect growRect;
  607.     long size;
  608.     short width;
  609.     short height;
  610.     
  611.     growRect.left = MIN_WINDOW_WIDTH;
  612.     growRect.top = MIN_WINDOW_HEIGHT;
  613.     growRect.right = (*GrayRgn)->rgnBBox.right;
  614.     growRect.bottom = (*GrayRgn)->rgnBBox.bottom - TITLE_BAR_HEIGHT;
  615.     
  616.     size = GrowWindow(whichWindow, Event.where, &growRect);
  617.     
  618.     if(size != 0) {
  619.         SetPort(whichWindow);
  620.         
  621.         InvalGrow(whichWindow);
  622.         
  623.         height = size >> 16; /* HiWord(size). */
  624.         width = size & 0xFFFF; /* LoWord(size). */
  625.         
  626.         SizeWindow(whichWindow, width, height, true);
  627.         /* Resize and redraw the scroll bars and grow icon. */
  628.         SizeDocument(whichWindow);
  629.     }
  630. }
  631.  
  632. /*
  633. ----------------------------------------------------------------------------------------------------
  634. INVAL GROW
  635.  
  636.     Invalidate the grow region of the window. This includes the area occupied by the scroll bars. */
  637.  
  638. void InvalGrow(whichWindow)
  639. WindowPtr whichWindow;
  640. {
  641.     Rect updateRect;
  642.     
  643.     updateRect = whichWindow->portRect;
  644.     
  645.     updateRect.top = updateRect.bottom - SCROLL_BAR_SIZE;
  646.     InvalRect(&updateRect);
  647.     
  648.     updateRect.top = whichWindow->portRect.top;
  649.     
  650.     updateRect.left = updateRect.right - SCROLL_BAR_SIZE;
  651.     InvalRect(&updateRect);
  652. }
  653.  
  654. /*
  655. ----------------------------------------------------------------------------------------------------
  656. CLOSE EVENT */
  657.  
  658. void CloseEvent(whichWindow)
  659. WindowPtr whichWindow;
  660. {
  661.     WindowPeek front;
  662.     
  663.     if(Event.modifiers & optionKey) {
  664.         ClosingAll = true;
  665.     }
  666.     if ((front = (WindowPeek) TopWindow) != nil) {
  667.     
  668.         if(front->windowKind < 0) {
  669.             CloseDeskAcc(front->windowKind);
  670.         }
  671.         else {
  672.         
  673.             if((front->windowKind == userKind) && (whichWindow != nil)) {
  674.             
  675.                 if(((WindowPeek) whichWindow)->refCon == DOCUMENT_WINDOW) {
  676.                     CloseDocument(whichWindow);
  677.                     
  678.                     if(TopPalette == TopWindow) {
  679.                         /* Find the new TopDocument. */
  680.                         LocateWindows();
  681.                         
  682.                         if(TopDocument != nil) {
  683.                             /* Ensure the TopDocument and its controls are hilited properly. */
  684.                             ActivateDocument(TopDocument, true);
  685.                         }
  686.                     }
  687.                 }
  688.                 else {
  689.                 
  690.                     if(TopDocument != nil) {
  691.                         /* Don't generate any events that might cause the TopDocument to be unhilited. */
  692.                         ShowHide(whichWindow, false);
  693.                     }
  694.                     else {
  695.                         /* Ensure an activate event is generated in case the next visible window does not
  696.                         belong to the application. */
  697.                         HideWindow(whichWindow);
  698.                     }
  699.                 }
  700.             }
  701.         }
  702.     }
  703. }
  704.